home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Add-On
/
Workbench Add-On - Volume 1.iso
/
BBS-Archive
/
Comm
/
term-source.lha
/
Extras
/
Source
/
term-Source.lha
/
termReviewBuffer.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-06-17
|
37KB
|
1,843 lines
/*
** termReviewBuffer.c
**
** Support routines for the review buffer
**
** Copyright © 1990-1995 by Olaf `Olsen' Barthel
** All Rights Reserved
*/
#include "termGlobal.h"
/* Handy signal masks. */
#define SIG_REVIEWPORT (1L << ReviewPort -> mp_SigBit)
#define SIG_REVIEWWINDOW (1L << ReviewWindow -> UserPort -> mp_SigBit)
/* Menu item codes. */
enum { MEN_SEARCH,MEN_REPEAT,MEN_CLEARBUF,MEN_QUITBUF };
/* Gadget ID codes. */
enum { GAD_SCROLLER, GAD_UP, GAD_DOWN };
STATIC struct NewMenu ReviewMenu[] =
{
{ NM_TITLE, NULL, 0 , 0, 0, (APTR)0},
{ NM_ITEM, NULL, 0 , 0, 0, (APTR)MEN_SEARCH},
{ NM_ITEM, NULL, 0 , 0, 0, (APTR)MEN_REPEAT},
{ NM_ITEM, NM_BARLABEL, 0 , 0, 0, (APTR)0},
{ NM_ITEM, NULL, 0 , 0, 0, (APTR)MEN_CLEARBUF},
{ NM_ITEM, NM_BARLABEL, 0 , 0, 0, (APTR)0},
{ NM_ITEM, NULL, 0 , 0, 0, (APTR)MEN_QUITBUF},
{ NM_END, 0, 0 , 0, 0, (APTR)0}
};
/* Local routines. */
STATIC VOID ReviewUpdatePot(VOID);
STATIC VOID __stdargs ReviewWrites(STRPTR String,...);
STATIC VOID __regargs PrintReviewLine(STRPTR Buffer,LONG Line);
STATIC VOID __regargs RefreshReview(LONG Top);
STATIC VOID __regargs ScrollReview(LONG Top);
STATIC BYTE ReviewQuery(VOID);
STATIC UBYTE __regargs GetReviewChar(BYTE WaitForIt);
/* Local variables. */
STATIC struct Menu *ReviewMenuStrip;
STATIC struct IBox ReviewBox = { -1 };
STATIC struct IOStdReq *ReviewWriteRequest,
*ReviewReadRequest;
STATIC struct MsgPort *ReviewPort,
*ReviewWritePort;
STATIC struct Gadget *Scroller,
*UpArrow,
*DownArrow;
STATIC UWORD RightBorderWidth;
STATIC struct Image *UpImage,
*DownImage;
STATIC UBYTE ReviewChar;
STATIC LONG ReviewColumns,ReviewLines,
ReviewTop = -1,ReviewGlobalLines;
STATIC BYTE SearchForward = TRUE,
IgnoreCase = TRUE,
WholeWords = FALSE;
STATIC UBYTE *ReviewLineWidths;
STATIC LONG ReviewMaxLines;
STATIC struct MsgQueue *ReviewQueue;
STATIC struct Process *ReviewProcess;
STATIC WORD ReviewPen;
STATIC BYTE ReviewSignal;
STATIC struct TextFont *LocalFont;
STATIC struct TTextAttr LocalTextFont;
STATIC UBYTE __far LocalTextFontName[MAX_FILENAME_LENGTH];
/* ReviewDeleteScroller(VOID):
*
* Delete scroller and arrow buttons.
*/
STATIC VOID
ReviewDeleteScroller(VOID)
{
if(Scroller)
{
DisposeObject(Scroller);
Scroller = NULL;
}
if(UpArrow)
{
DisposeObject(UpArrow);
UpArrow = NULL;
}
if(DownArrow)
{
DisposeObject(DownArrow);
DownArrow = NULL;
}
if(UpImage)
{
DisposeObject(UpImage);
UpImage = NULL;
}
if(DownImage)
{
DisposeObject(DownImage);
DownImage = NULL;
}
}
/* ReviewCreateScroller(struct Screen *Screen):
*
* Create scroller and arrow buttons.
*/
STATIC BYTE __regargs
ReviewCreateScroller(struct Screen *Screen)
{
struct DrawInfo *DrawInfo;
BYTE Result = FALSE;
if(DrawInfo = GetScreenDrawInfo(Screen))
{
struct Image *SizeImage;
ULONG SizeWidth,
SizeHeight,
ArrowHeight;
UWORD SizeType;
if(Screen -> Flags & SCREENHIRES)
{
SizeWidth = 18;
SizeHeight = 10;
SizeType = SYSISIZE_MEDRES;
}
else
{
SizeWidth = 13;
SizeHeight = 11;
SizeType = SYSISIZE_LOWRES;
}
if(SizeImage = (struct Image *)NewObject(NULL,"sysiclass",
SYSIA_Size, SizeType,
SYSIA_Which, SIZEIMAGE,
SYSIA_DrawInfo, DrawInfo,
TAG_DONE))
{
GetAttr(IA_Width, SizeImage,&SizeWidth);
GetAttr(IA_Height, SizeImage,&SizeHeight);
DisposeObject(SizeImage);
RightBorderWidth = SizeWidth;
if(UpImage = (struct Image *)NewObject(NULL,"sysiclass",
SYSIA_Size, SizeType,
SYSIA_Which, UPIMAGE,
SYSIA_DrawInfo, DrawInfo,
TAG_DONE))
{
GetAttr(IA_Height,UpImage,&ArrowHeight);
if(DownImage = (struct Image *)NewObject(NULL,"sysiclass",
SYSIA_Size, SizeType,
SYSIA_Which, DOWNIMAGE,
SYSIA_DrawInfo, DrawInfo,
TAG_DONE))
{
if(Scroller = NewObject(NULL,"propgclass",
GA_ID, GAD_SCROLLER,
GA_Top, Screen -> WBorTop + Screen -> Font -> ta_YSize + 2,
GA_RelHeight, -(Screen -> WBorTop + Screen -> Font -> ta_YSize + 2 + SizeHeight + 1 + 2 * ArrowHeight),
GA_Width, SizeWidth - 8,
GA_RelRight, -(SizeWidth - 5),
GA_Immediate, TRUE,
GA_FollowMouse, TRUE,
GA_RelVerify, TRUE,
GA_RightBorder, TRUE,
PGA_Freedom, FREEVERT,
PGA_NewLook, TRUE,
PGA_Borderless, TRUE,
PGA_Visible, 1,
PGA_Total, 1,
TAG_DONE))
{
STATIC struct TagItem ArrowMappings[] = { GA_ID,GA_ID,TAG_END };
if(UpArrow = NewObject(NULL,"buttongclass",
GA_ID, GAD_UP,
GA_Image, UpImage,
GA_RelRight, -(SizeWidth - 1),
GA_RelBottom, -(SizeHeight - 1 + 2 * ArrowHeight),
GA_Height, ArrowHeight,
GA_Width, SizeWidth,
GA_Immediate, TRUE,
GA_RelVerify, TRUE,
GA_Previous, Scroller,
GA_RightBorder, TRUE,
ICA_TARGET, ICTARGET_IDCMP,
ICA_MAP, ArrowMappings,
TAG_DONE))
{
if(DownArrow = NewObject(NULL,"buttongclass",
GA_ID, GAD_DOWN,
GA_Image, DownImage,
GA_RelRight, -(SizeWidth - 1),
GA_RelBottom, -(SizeHeight - 1 + ArrowHeight),
GA_Height, ArrowHeight,
GA_Width, SizeWidth,
GA_Immediate, TRUE,
GA_RelVerify, TRUE,
GA_Previous, UpArrow,
GA_RightBorder, TRUE,
ICA_TARGET, ICTARGET_IDCMP,
ICA_MAP, ArrowMappings,
TAG_DONE))
Result = TRUE;
}
}
}
}
}
FreeScreenDrawInfo(Screen,DrawInfo);
}
return(Result);
}
/* ReviewUpdatePot():
*
* Update size and position of the scroller gadget.
*/
STATIC VOID
ReviewUpdatePot()
{
if(ReviewGlobalLines)
{
SetGadgetAttrs(Scroller,ReviewWindow,NULL,
PGA_Top, ReviewTop,
PGA_Visible, ReviewLines,
PGA_Total, ReviewGlobalLines,
TAG_DONE);
}
}
/* ReviewUp(LONG Count):
*
* Move the contents of the review buffer up.
*/
STATIC VOID __regargs
ReviewUp(LONG Count)
{
if(BufferLines)
{
if(Count == 1)
{
if(ReviewTop)
{
WORD i;
for(i = ReviewMaxLines - 2 ; i >= 0 ; i--)
ReviewLineWidths[i + 1] = ReviewLineWidths[i];
ReviewTop--;
ReviewWrites("\33[T");
ObtainSemaphore(BufferSemaphore);
PrintReviewLine(BufferLines[ReviewTop],1);
ReviewUpdatePot();
ReleaseSemaphore(BufferSemaphore);
}
}
else
{
LONG NewTop = ReviewTop;
if(NewTop >= Count)
NewTop -= Count;
else
NewTop = 0;
if(NewTop != ReviewTop)
{
ScrollReview(NewTop);
ReviewUpdatePot();
}
}
}
}
/* ReviewDown(LONG Count):
*
* Move the contents of the review buffer down.
*/
STATIC VOID __regargs
ReviewDown(LONG Count)
{
if(BufferLines)
{
if(Count == 1)
{
if(ReviewTop + ReviewLines < Lines)
{
LONG Last;
WORD i;
for(i = 0 ; i < ReviewMaxLines - 1 ; i++)
ReviewLineWidths[i] = ReviewLineWidths[i + 1];
ReviewTop++;
ReviewWrites("\33[S");
ObtainSemaphore(BufferSemaphore);
if((Last = ReviewTop + ReviewLines) < Lines)
PrintReviewLine(BufferLines[Last],ReviewLines + 1);
ReviewUpdatePot();
ReleaseSemaphore(BufferSemaphore);
}
}
else
{
LONG NewTop = ReviewTop;
if((NewTop + Count + ReviewLines) > Lines)
{
if((NewTop = Lines - ReviewLines) < 0)
NewTop = 0;
}
else
NewTop += Count;
if(NewTop != ReviewTop)
{
ScrollReview(NewTop);
ReviewUpdatePot();
}
}
}
}
/* ReviewWrites(STRPTR String,...):
*
* Write a string into the review buffer window.
*/
STATIC VOID __stdargs
ReviewWrites(STRPTR String,...)
{
UBYTE LocalBuffer[256];
va_list VarArgs;
va_start(VarArgs,String);
VSPrintf(LocalBuffer,String,VarArgs);
va_end(VarArgs);
ReviewWriteRequest -> io_Command = CMD_WRITE;
ReviewWriteRequest -> io_Data = LocalBuffer;
ReviewWriteRequest -> io_Length = strlen(LocalBuffer);
DoIO(ReviewWriteRequest);
}
/* FilterReviewLine(register STRPTR Line,register LONG Length):
*
* Replace non-printable characters in the text line
* to be printed.
*/
STATIC STRPTR __regargs
FilterReviewLine(register STRPTR Line,register LONG Length)
{
STATIC UBYTE __far ISO[256] =
{
46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126, 46,
46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
};
STATIC UBYTE __far TempBuffer[256];
register STRPTR Destination = TempBuffer;
while(Length--)
*Destination++ = ISO[*Line++];
return(TempBuffer);
}
/* PrintReviewLine(STRPTR Buffer,LONG Line):
*
* Write the contents of a buffer line into the review buffer window.
*/
STATIC VOID __regargs
PrintReviewLine(STRPTR Buffer,LONG Line)
{
WORD Length = Buffer[-1];
if(Length > ReviewColumns)
Length = ReviewColumns;
ReviewWrites("\33[%ldH",Line);
ReviewWriteRequest -> io_Command = CMD_WRITE;
ReviewWriteRequest -> io_Data = FilterReviewLine(Buffer,Length);
ReviewWriteRequest -> io_Length = Length;
DoIO(ReviewWriteRequest);
if(Length < ReviewLineWidths[Line - 1])
ReviewWrites("\33[0K");
ReviewLineWidths[Line - 1] = Length;
}
/* RefreshReview(LONG Top):
*
* Refresh the contents of the review buffer window.
*/
STATIC VOID __regargs
RefreshReview(LONG Top)
{
LONG i,Last,Line = 0;
ObtainSemaphore(BufferSemaphore);
ReviewGlobalLines = Lines;
if((Last = Top + ReviewLines + 1) >= Lines)
{
Last = Lines;
if((Top = Last - ReviewLines) < 0)
Top = 0;
ReviewTop = Top;
}
if(BufferLines)
{
for(i = Top ; i < Last ; i++)
PrintReviewLine(BufferLines[i],++Line);
}
if(Line <= ReviewLines)
{
if(Line)
{
for(i = Line - 1 ; i < ReviewLines ; i++)
ReviewLineWidths[i] = 0;
}
if(Screen)
ReviewWrites("\33[0J\33[3%ldm",ReviewPen);
else
ReviewWrites("\33[0J");
}
ReleaseSemaphore(BufferSemaphore);
}
/* MoveUp(VOID):
*
* Move the review buffer contents up a line.
*/
STATIC VOID
MoveUp(VOID)
{
LONG i;
for(i = 0 ; i < ReviewMaxLines - 1 ; i++)
ReviewLineWidths[i] = ReviewLineWidths[i + 1];
ReviewWrites("\33[S");
ObtainSemaphore(BufferSemaphore);
PrintReviewLine(BufferLines[ReviewTop + ReviewLines],ReviewLines + 1);
ReleaseSemaphore(BufferSemaphore);
}
/* ScrollReview(LONG Top):
*
* Refresh the contents of the review buffer window, reprint
* as few lines as possible.
*/
STATIC VOID __regargs
ScrollReview(LONG Top)
{
LONG i,Last,Line = 0,Delta,Total;
ObtainSemaphore(BufferSemaphore);
ReviewGlobalLines = Lines;
Delta = Top - ReviewTop;
ReviewTop = Top;
if((Last = Top + ReviewLines + 1) >= Lines)
Last = Lines;
Total = Last - Top;
if(ABS(Delta) < ReviewLines)
{
if(!Delta)
{
ReleaseSemaphore(BufferSemaphore);
return;
}
else
{
if(Delta < 0)
{
Last = Top - Delta;
for(i = ReviewMaxLines - 1 ; i > -Delta ; i--)
ReviewLineWidths[i] = ReviewLineWidths[i + Delta];
ReviewWrites("\33[%ldT",-Delta);
}
else
{
for(i = Delta ; i < ReviewMaxLines ; i++)
ReviewLineWidths[i - Delta] = ReviewLineWidths[i];
Top += ReviewLines - Delta;
Line = ReviewLines - Delta;
ReviewWrites("\33[%ldS",Delta);
}
}
}
if(BufferLines)
{
for(i = Top ; i < Last ; i++)
PrintReviewLine(BufferLines[i],++Line);
}
if(Total <= ReviewLines)
ReviewWrites("\33[0J");
ReleaseSemaphore(BufferSemaphore);
}
/* ReviewQuery():
*
* Update the current review buffer window dimensions.
*/
STATIC BYTE
ReviewQuery()
{
struct ConUnit *Unit = (struct ConUnit *)ReviewWriteRequest -> io_Unit;
BYTE Refresh = FALSE;
memset(ReviewLineWidths,0,ReviewMaxLines);
if(ReviewColumns != Unit -> cu_XMax)
{
Refresh = TRUE;
ReviewColumns = Unit -> cu_XMax;
}
if(ReviewLines != Unit -> cu_YMax)
{
Refresh = TRUE;
if(Unit -> cu_YMax < ReviewGlobalLines)
{
LONG Delta = Unit -> cu_YMax - ReviewLines;
ReviewLines = Unit -> cu_YMax;
if(Delta > 0)
{
if((ReviewTop = ReviewTop - Delta) < 0)
ReviewTop = 0;
}
else
{
ReviewTop -= Delta;
if(ReviewTop + ReviewLines > ReviewGlobalLines)
ReviewTop = ReviewGlobalLines - ReviewLines;
}
}
else
{
ReviewTop = 0;
ReviewLines = ReviewGlobalLines;
}
}
if(Refresh)
ReviewUpdatePot();
return(Refresh);
}
/* GetReviewChar(BYTE WaitForIt):
*
* Get the next character present at the console read port.
*/
STATIC UBYTE __regargs
GetReviewChar(BYTE WaitForIt)
{
UBYTE Char;
if(!WaitForIt)
{
if(!CheckIO(ReviewReadRequest))
return(0);
}
WaitIO(ReviewReadRequest);
Char = ReviewChar;
ReviewReadRequest -> io_Command = CMD_READ;
ReviewReadRequest -> io_Data = &ReviewChar;
ReviewReadRequest -> io_Length = 1;
SetSignal(0,SIG_REVIEWPORT);
SendIO(ReviewReadRequest);
return(Char);
}
/* MarkReviewLine(STRPTR Buffer,LONG Line,LONG Column,LONG Len):
*
* Similar to PrintReviewLine(), but also allows to mark a
* certain word on the line.
*/
STATIC VOID __regargs
MarkReviewLine(STRPTR Buffer,LONG Line,LONG Column,LONG Len)
{
WORD Length = Buffer[-1];
if(Length > ReviewColumns)
Length = ReviewColumns;
ReviewWrites("\33[%ldH",Line);
if(Length <= Column)
{
ReviewWriteRequest -> io_Command = CMD_WRITE;
ReviewWriteRequest -> io_Data = Buffer;
ReviewWriteRequest -> io_Length = Length;
DoIO(ReviewWriteRequest);
ReviewWrites("\33[0K");
}
else
{
ReviewWriteRequest -> io_Command = CMD_WRITE;
ReviewWriteRequest -> io_Data = Buffer;
ReviewWriteRequest -> io_Length = Column;
DoIO(ReviewWriteRequest);
ReviewWrites("\33[7;3%ldm",ReviewPen);
ReviewWriteRequest -> io_Command = CMD_WRITE;
ReviewWriteRequest -> io_Data = &Buffer[Column];
ReviewWriteRequest -> io_Length = Len;
DoIO(ReviewWriteRequest);
ReviewWrites("\33[0;3%ldm",ReviewPen);
if(Column + Len < Length)
{
ReviewWriteRequest -> io_Command = CMD_WRITE;
ReviewWriteRequest -> io_Data = &Buffer[Column + Len];
ReviewWriteRequest -> io_Length = Length - (Column + Len);
DoIO(ReviewWriteRequest);
}
ReviewWrites("\33[0K");
}
}
/* ReviewMarkArea(LONG Top,LONG Column,LONG Line,LONG Len,BYTE FullRefresh):
*
* Mark a word on the current display.
*/
STATIC VOID __regargs
ReviewMarkArea(LONG Top,LONG Column,LONG Line,LONG Len,BYTE FullRefresh)
{
STATIC LONG LastMarked = -1;
LONG i,Last,LineIndex = 0;
ReviewGlobalLines = Lines;
ObtainSemaphore(BufferSemaphore);
if((Last = Top + ReviewLines + 1) >= Lines)
Last = Lines;
if(FullRefresh)
{
if(BufferLines)
{
for(i = Top ; i < Last ; i++)
{
if(i != Line)
PrintReviewLine(BufferLines[i],++LineIndex);
else
MarkReviewLine(BufferLines[i],++LineIndex,Column,Len);
}
}
if(LineIndex <= ReviewLines)
ReviewWrites("\33[0J");
}
else
{
if(BufferLines)
{
for(i = Top ; i < Last ; i++)
{
LineIndex++;
if(i == LastMarked)
PrintReviewLine(BufferLines[i],LineIndex);
if(i == Line)
MarkReviewLine(BufferLines[i],LineIndex,Column,Len);
}
}
}
LastMarked = Line;
ReleaseSemaphore(BufferSemaphore);
}
/* ReviewSearch(struct SearchInfo *SearchInfo):
*
* Search for a certain word in the text buffer.
*/
STATIC VOID __regargs
ReviewSearch(struct SearchInfo *SearchInfo,STRPTR SearchBuffer)
{
LT_LockWindow(ReviewWindow);
if(Lines)
{
LONG LineNumber;
ObtainSemaphore(BufferSemaphore);
LineNumber = SearchTextBuffer(SearchInfo);
ReleaseSemaphore(BufferSemaphore);
if(LineNumber == -1)
{
RefreshReview(ReviewTop);
MyEasyRequest(ReviewWindow,LocaleString(MSG_TERMBUFFER_DID_NOT_FIND_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SearchBuffer);
SearchInfo -> FoundY = -1;
}
else
{
if(LineNumber < ReviewTop || LineNumber > ReviewTop + ReviewLines)
{
if(LineNumber + ReviewLines > Lines)
{
ReviewTop = Lines - ReviewLines;
if(ReviewTop < 0)
ReviewTop = 0;
}
else
ReviewTop = LineNumber;
ReviewUpdatePot();
ReviewMarkArea(ReviewTop,SearchInfo -> FoundX,LineNumber,SearchInfo -> PatternWidth,TRUE);
}
else
ReviewMarkArea(ReviewTop,SearchInfo -> FoundX,LineNumber,SearchInfo -> PatternWidth,FALSE);
}
}
else
MyEasyRequest(ReviewWindow,LocaleString(MSG_GLOBAL_NOTHING_IN_THE_BUFFER_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
LT_UnlockWindow(ReviewWindow);
}
STATIC VOID
LocalDeleteReview(VOID)
{
if(ReviewReadRequest)
{
if(ReviewReadRequest -> io_Device)
{
if(!CheckIO(ReviewReadRequest))
AbortIO(ReviewReadRequest);
WaitIO(ReviewReadRequest);
}
FreeVecPooled(ReviewReadRequest);
ReviewReadRequest = NULL;
}
if(ReviewWriteRequest)
{
if(ReviewWriteRequest -> io_Device)
CloseDevice(ReviewWriteRequest);
DeleteIORequest(ReviewWriteRequest);
ReviewWriteRequest = NULL;
}
if(ReviewWindow)
{
PutWindowInfo(WINDOW_REVIEW,ReviewWindow -> LeftEdge,ReviewWindow -> TopEdge,ReviewWindow -> Width,ReviewWindow -> Height);
LT_DeleteWindowLock(ReviewWindow);
ClearMenuStrip(ReviewWindow);
CloseWindow(ReviewWindow);
ReviewWindow = NULL;
}
if(LocalFont)
{
CloseFont(LocalFont);
LocalFont = NULL;
}
if(ReviewMenuStrip)
{
FreeMenus(ReviewMenuStrip);
ReviewMenuStrip = NULL;
}
ReviewDeleteScroller();
if(ReviewWritePort)
{
DeleteMsgPort(ReviewWritePort);
ReviewWritePort = NULL;
}
if(ReviewPort)
{
DeleteMsgPort(ReviewPort);
ReviewPort = NULL;
}
if(ReviewSignal != -1)
{
FreeSignal(ReviewSignal);
ReviewSignal = -1;
}
if(ReviewLineWidths)
{
FreeVecPooled(ReviewLineWidths);
ReviewLineWidths = NULL;
}
if(ReviewQueue)
{
DeleteMsgQueue(ReviewQueue);
ReviewQueue = NULL;
}
}
STATIC BOOLEAN
LocalCreateReview(VOID)
{
if(ReviewBox . Left == -1)
{
ReviewBox . Left = 0;
ReviewBox . Top = Window -> WScreen -> BarHeight + 1;
ReviewBox . Width = Window -> WScreen -> Width;
ReviewBox . Height = Window -> WScreen -> Height - (Window -> WScreen -> BarHeight + 1);
}
if((ReviewSignal = AllocSignal(-1)) != -1)
{
if(ReviewQueue = CreateMsgQueue(NULL,0))
{
if(ReviewCreateScroller(Window -> WScreen))
{
LocalizeMenu(ReviewMenu,MSG_TERMREVIEW_PROJECT_MEN);
if(ReviewMenuStrip = CreateMenus(ReviewMenu,TAG_DONE))
{
if(LayoutMenus(ReviewMenuStrip,VisualInfo,
AmigaGlyph ? GTMN_AmigaKey : TAG_IGNORE, AmigaGlyph,
CheckGlyph ? GTMN_Checkmark : TAG_IGNORE, CheckGlyph,
GTMN_TextAttr, &UserFont,
GTMN_NewLookMenus, TRUE,
TAG_DONE))
{
LONG Left = 0,
Top = 0,
Width = 0,
Height = 0;
GetWindowInfo(WINDOW_REVIEW,&Left,&Top,&Width,&Height,NULL,Window -> WScreen -> WBorTop + Window -> WScreen -> WBorBottom + 1 + Window -> WScreen -> Font -> ta_YSize + 10 * CurrentFont -> tf_YSize);
if(ReviewWindow = OpenWindowTags(NULL,
WA_Left, Left,
WA_Top, Top,
WA_Width, Width,
WA_Height, Height,
WA_MinWidth, Window -> WScreen -> WBorLeft + RightBorderWidth + 15 * CurrentFont -> tf_XSize,
WA_MinHeight, Window -> WScreen -> WBorTop + Window -> WScreen -> WBorBottom + 1 + Window -> WScreen -> Font -> ta_YSize + 2 * CurrentFont -> tf_YSize,
WA_MaxWidth, Window -> WScreen -> Width,
WA_MaxHeight, Window -> WScreen -> Height,
WA_DragBar, TRUE,
WA_CloseGadget, TRUE,
WA_DepthGadget, TRUE,
WA_SizeGadget, TRUE,
WA_SizeBRight, TRUE,
WA_MenuHelp, TRUE,
WA_IDCMP, IDCMP_IDCMPUPDATE | IDCMP_GADGETDOWN | IDCMP_SIZEVERIFY | IDCMP_MOUSEMOVE | IDCMP_MENUPICK | IDCMP_MENUHELP,
WA_Title, LocaleString(MSG_TERMREVIEW_REVIEWBUFFER_TXT),
WA_CustomScreen, Window -> WScreen,
WA_SimpleRefresh, TRUE,
WA_RMBTrap, TRUE,
WA_Activate, TRUE,
WA_NewLookMenus, TRUE,
WA_Zoom, &ReviewBox,
WA_Gadgets, Scroller,
AmigaGlyph ? WA_AmigaKey : TAG_IGNORE, AmigaGlyph,
CheckGlyph ? WA_Checkmark : TAG_IGNORE, CheckGlyph,
TAG_DONE))
{
ReviewMaxLines = (ReviewWindow -> WScreen -> Height - (ReviewWindow -> BorderTop + ReviewWindow -> BorderBottom)) / CurrentFont -> tf_YSize;
if(ReviewLineWidths = (UBYTE *)AllocVecPooled(ReviewMaxLines,MEMF_ANY | MEMF_CLEAR))
{
SetMenuStrip(ReviewWindow,ReviewMenuStrip);
memcpy(&LocalTextFont,&TextAttr,sizeof(struct TTextAttr));
LocalTextFont . tta_Name = LocalTextFontName;
LocalTextFont . tta_YSize = Config -> TerminalConfig -> TextFontHeight;
strcpy(LocalTextFontName,Config -> TerminalConfig -> TextFontName);
if(!Config -> CaptureConfig -> ConvertChars && Config -> TerminalConfig -> FontMode != FONT_STANDARD)
{
strcpy(LocalTextFontName,Config -> TerminalConfig -> IBMFontName);
LocalTextFont . tta_YSize = Config -> TerminalConfig -> IBMFontHeight;
}
if(LocalFont = OpenDiskFont(&LocalTextFont))
SetFont(ReviewWindow -> RPort,LocalFont);
if(ReviewWritePort = CreateMsgPort())
{
if(ReviewPort = CreateMsgPort())
{
if(ReviewWriteRequest = CreateIORequest(ReviewPort,sizeof(struct IOStdReq)))
{
if(ReviewReadRequest = (struct IOStdReq *)AllocVecPooled(sizeof(struct IOStdReq),MEMF_ANY | MEMF_CLEAR))
{
ReviewWriteRequest -> io_Data = ReviewWindow;
if(!OpenDevice("console.device",CONU_SNIPMAP,ReviewWriteRequest,CONFLAG_NODRAW_ON_NEWSIZE))
{
CopyMem(ReviewWriteRequest,ReviewReadRequest,sizeof(struct IOStdReq));
ReviewReadRequest -> io_Message . mn_ReplyPort = ReviewPort;
ReviewReadRequest -> io_Command = CMD_READ;
ReviewReadRequest -> io_Data = &ReviewChar;
ReviewReadRequest -> io_Length = 1;
SendIO(ReviewReadRequest);
switch(Config -> ScreenConfig -> ColourMode)
{
case COLOUR_AMIGA:
case COLOUR_MONO:
ReviewPen = 1;
break;
case COLOUR_EIGHT:
case COLOUR_SIXTEEN:
ReviewPen = 7;
break;
}
ReviewPen = GetPenIndex(ReviewPen) & 7;
if(Screen)
ReviewWrites("\33[0 p\33[11;12\173\33[3%ldm",ReviewPen);
else
ReviewWrites("\33[0 p\33[11;12\173");
ObtainSemaphore(BufferSemaphore);
if(ReviewTop == -1 || !Config -> CaptureConfig -> RememberBufferWindow)
{
switch(Config -> CaptureConfig -> OpenBufferWindow)
{
case BUFFER_TOP:
ReviewTop = 0;
break;
case BUFFER_END:
if((ReviewTop = Lines - ReviewLines) < 0)
ReviewTop = 0;
break;
default:
ReviewTop = 0;
break;
}
}
if(ReviewTop > Lines - ReviewLines)
{
if((ReviewTop = Lines - ReviewLines) < 0)
ReviewTop = 0;
}
ReviewGlobalLines = Lines;
ReleaseSemaphore(BufferSemaphore);
ReviewQuery();
RefreshReview(ReviewTop);
ReviewUpdatePot();
ReviewWindow -> Flags &= ~WFLG_RMBTRAP;
return(TRUE);
}
}
}
}
}
}
}
}
}
}
}
}
LocalDeleteReview();
return(FALSE);
}
/* LocalUpdateReview():
*
* Update the contents of the review buffer window.
*/
STATIC VOID __regargs
LocalUpdateReview(BYTE Force)
{
if(Force)
{
if(Lines)
{
if(ReviewTop > 0)
{
SetGadgetAttrs(Scroller,ReviewWindow,NULL,
PGA_Top,--ReviewTop,
TAG_DONE);
}
else
MoveUp();
}
}
else
{
if(Lines >= ReviewGlobalLines && ReviewGlobalLines <= ReviewLines)
{
if(ReviewLines < ((struct ConUnit *)ReviewWriteRequest -> io_Unit) -> cu_YMax)
{
if(((struct ConUnit *)ReviewWriteRequest -> io_Unit) -> cu_YMax < Lines)
ReviewLines = ((struct ConUnit *)ReviewWriteRequest -> io_Unit) -> cu_YMax;
else
ReviewLines = Lines;
}
RefreshReview(ReviewTop);
}
}
ReviewGlobalLines = Lines;
if(!Lines)
{
SetGadgetAttrs(Scroller,ReviewWindow,NULL,
PGA_Top, ReviewTop = 0,
PGA_Visible, 1,
PGA_Total, 1,
TAG_DONE);
ReviewWrites("\f\33[3%ldm",ReviewPen);
}
else
ReviewUpdatePot();
}
/* LocalMoveReview(BYTE Mode):
*
* Move the currently visible review area.
*/
STATIC VOID __regargs
LocalMoveReview(BYTE Mode)
{
LONG NewTop;
switch(Mode)
{
case REVIEW_MOVE_TOP:
if(ReviewTop)
{
ScrollReview(0);
ReviewUpdatePot();
}
break;
case REVIEW_MOVE_BOTTOM:
NewTop = Lines - ReviewLines;
if(NewTop < 0)
NewTop = 0;
if(ReviewTop != NewTop)
{
ScrollReview(NewTop);
ReviewUpdatePot();
}
break;
case REVIEW_MOVE_UP:
ReviewUp(ReviewLines);
break;
case REVIEW_MOVE_DOWN:
ReviewDown(ReviewLines);
break;
}
}
STATIC VOID __stdargs
ReviewClientDestructor(struct DataMsg *Item)
{
Signal((struct Task *)Item -> Client,Item -> Mask);
}
STATIC VOID __regargs
ReviewSerWrite(APTR Data,LONG Size)
{
struct DataMsg Msg;
InitMsgItem(&Msg,ReviewClientDestructor);
Msg . Type = DATAMSGTYPE_WRITE;
Msg . Data = Data;
Msg . Size = Size;
Msg . Client = ReviewProcess;
Msg . Mask = ReviewSignal;
Forbid();
ClrSignal(Msg . Mask);
PutMsgItem(SpecialQueue,(struct MsgItem *)&Msg);
Wait(Msg . Mask);
Permit();
}
STATIC VOID __saveds
ReviewProcessEntry(VOID)
{
struct Process *Father = ThisProcess;
if(LocalCreateReview())
{
UBYTE SearchBuffer[256];
struct Hook HistoryHook;
ULONG Signals;
BOOLEAN Done = FALSE;
struct SearchInfo *SearchInfo = NULL;
struct SearchContext *Context = NULL;
HistoryHook . h_Data = &ReviewBufferHistory;
Forbid();
ReviewProcess = (struct Process *)SysBase -> ThisTask;
Signal(ThisProcess,SIG_HANDSHAKE);
Permit();
do
{
Signals = Wait(SIG_KILL | SIG_REVIEWPORT | SIG_REVIEWWINDOW | ReviewQueue -> SigMask);
if(Signals & SIG_KILL)
break;
if(Signals & SIG_REVIEWPORT)
{
UBYTE Char;
/* Control sequence available? */
if((Char = GetReviewChar(FALSE)) == CSI)
{
UBYTE InputBuffer[257];
WORD Count = 0;
/* Try to read the entire sequence. */
while(Char = GetReviewChar(FALSE))
{
InputBuffer[Count++] = Char;
if(Char != ' ' && Char != ';' && (Char < '0' || Char > '9'))
break;
}
/* Provide termination. */
InputBuffer[Count] = 0;
/* Raw event? */
if(!strcmp(InputBuffer,"?~"))
GuideDisplay(CONTEXT_TEXTBUFFER);
if(!strcmp(InputBuffer,"A"))
ReviewUp(1);
if(!strcmp(InputBuffer,"B"))
ReviewDown(1);
if(!strcmp(InputBuffer,"T"))
ReviewUp(ReviewLines);
if(!strcmp(InputBuffer,"S"))
ReviewDown(ReviewLines);
if(!memcmp(InputBuffer,"11;",3))
{
Done = TRUE;
if(!(SetSignal(0,SIG_KILL) & SIG_KILL))
Father = NULL;
}
if(!memcmp(InputBuffer,"12;",3))
{
if(ReviewQuery())
RefreshReview(ReviewTop);
}
if(!strcmp(InputBuffer,"0 v"))
{
struct DataMsg Msg;
InitMsgItem(&Msg,ReviewClientDestructor);
Msg . Type = DATAMSGTYPE_WRITECLIP;
Msg . Size = Config -> ClipConfig -> ClipboardUnit;
Msg . Client = ReviewProcess;
Msg . Mask = ReviewSignal;
Forbid();
ClrSignal(Msg . Mask);
PutMsgItem(SpecialQueue,(struct MsgItem *)&Msg);
Wait(Msg . Mask);
Permit();
}
}
else
{
if(Char)
{
if(Config -> SerialConfig -> StripBit8)
Char &= 0x7F;
if(Status == STATUS_HOLDING)
{
if(Char == XOF)
{
ReviewSerWrite(&Char,1);
Status = STATUS_READY;
}
}
else
{
/* Convert chars
* as approriate.
*/
if(Char == '\n')
{
switch(Config -> TerminalConfig -> SendLF)
{
case EOL_LF:
goto SendIt;
case EOL_LFCR:
ReviewSerWrite("\n\r",2);
break;
case EOL_CRLF:
ReviewSerWrite("\r\n",2);
break;
case EOL_CR:
ReviewSerWrite("\r",1);
break;
}
}
if(Char == '\r')
{
switch(Config -> TerminalConfig -> SendCR)
{
case EOL_CR:
goto SendIt;
case EOL_LFCR:
ReviewSerWrite("\n\r",2);
break;
case EOL_CRLF:
ReviewSerWrite("\r\n",2);
break;
case EOL_LF:
ReviewSerWrite("\n",1);
break;
}
}
/* Stop in/output. */
if(Char == XON)
{
if(Config -> SerialConfig -> PassThrough)
ReviewSerWrite(&Char,1);
if(Config -> SerialConfig -> xONxOFF)
Status = STATUS_HOLDING;
}
/* Restart in/output. */
if(Char == XOF)
{
if(Config -> SerialConfig -> PassThrough)
ReviewSerWrite(&Char,1);
if(Status == STATUS_HOLDING)
Status = STATUS_READY;
}
/* Convert special
* Amiga characters into
* alien IBM dialect.
*/
SendIt: if(Config -> TerminalConfig -> FontMode == FONT_IBM)
{
if(IBMConversion[Char])
ReviewSerWrite(&IBMConversion[Char],1);
else
ReviewSerWrite(&Char,1);
}
else
ReviewSerWrite(&Char,1);
}
}
}
}
if(Signals & SIG_REVIEWWINDOW)
{
struct IntuiMessage *Message;
struct MenuItem *MenuItem;
struct TagItem *TagList;
ULONG MsgClass;
UWORD MsgCode,
MsgQualifier;
while(Message = (struct IntuiMessage *)GetMsg(ReviewWindow -> UserPort))
{
if(Context && Context -> SearchWindow == Message -> IDCMPWindow)
{
MsgClass = NULL;
if(HandleSearchMessage(Context,&Message))
{
BOOLEAN Ok = Context -> Ok;
DeleteSearchContext(Context);
Context = NULL;
if(Ok)
{
if(SearchInfo)
DeleteSearchInfo(SearchInfo);
if(SearchInfo = CreateSearchInfo(SearchBuffer,SearchForward,IgnoreCase,WholeWords))
ReviewSearch(SearchInfo,SearchBuffer);
}
else
{
if(SearchInfo)
{
DeleteSearchInfo(SearchInfo);
SearchInfo = NULL;
}
}
}
}
else
{
MsgClass = Message -> Class;
MsgCode = Message -> Code;
MsgQualifier = Message -> Qualifier;
TagList = (struct TagItem *)Message -> IAddress;
ReplyMsg((struct Message *)Message);
}
switch(MsgClass)
{
case IDCMP_MENUHELP:
GuideDisplay(CONTEXT_BUFFER_MENU);
break;
case IDCMP_IDCMPUPDATE:
switch(GetTagData(GA_ID,0,TagList))
{
case GAD_UP: ReviewUp(1);
break;
case GAD_DOWN: ReviewDown(1);
break;
}
break;
case IDCMP_GADGETDOWN:
case IDCMP_MOUSEMOVE:
if(ReviewGlobalLines > ReviewLines)
{
LONG NewTop;
if(GetAttr(PGA_Top,Scroller,(ULONG *)&NewTop))
ScrollReview(NewTop);
}
break;
case IDCMP_MENUPICK:
while(MsgCode != MENUNULL)
{
MenuItem = ItemAddress(ReviewMenuStrip,MsgCode);
switch((ULONG)GTMENUITEM_USERDATA(MenuItem))
{
case MEN_SEARCH:
if(Context)
LT_ShowWindow(Context -> SearchHandle,TRUE);
else
Context = CreateSearchContext(ReviewWindow,SearchBuffer,&HistoryHook,&SearchForward,&IgnoreCase,&WholeWords);
break;
case MEN_REPEAT:
if(Context)
LT_ShowWindow(Context -> SearchHandle,TRUE);
else
{
if(SearchInfo)
ReviewSearch(SearchInfo,SearchBuffer);
else
Context = CreateSearchContext(ReviewWindow,SearchBuffer,&HistoryHook,&SearchForward,&IgnoreCase,&WholeWords);
}
break;
case MEN_QUITBUF:
Done = TRUE;
if(!(SetSignal(0,SIG_KILL) & SIG_KILL))
Father = NULL;
break;
case MEN_CLEARBUF:
if(Lines)
{
if((MsgQualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)) || !Config -> MiscConfig -> ProtectiveMode)
FreeBuffer();
else
{
if(MyEasyRequest(ReviewWindow,LocaleString(MSG_TERMBUFFER_BUFFER_STILL_HOLDS_LINES_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT),Lines))
FreeBuffer();
}
}
break;
}
MsgCode = MenuItem -> NextSelect;
}
break;
}
}
}
if(Signals & ReviewQueue -> SigMask)
{
struct DataMsg *Msg;
while(Msg = (struct DataMsg *)GetMsgItem(ReviewQueue))
{
switch(Msg -> Type)
{
case DATAMSGTYPE_UPDATEREVIEW:
LocalUpdateReview(Msg -> Size);
break;
case DATAMSGTYPE_MOVEREVIEW:
LocalMoveReview(Msg -> Size);
break;
}
DeleteMsgItem(Msg);
}
}
}
while(!Done);
if(Context)
DeleteSearchContext(Context);
if(SearchInfo)
DeleteSearchInfo(SearchInfo);
LocalDeleteReview();
}
Forbid();
ReviewProcess = NULL;
if(Father)
Signal(Father,SIG_HANDSHAKE);
else
CheckItem(MEN_REVIEW_WINDOW,FALSE);
}
VOID __regargs
UpdateReview(BYTE Force)
{
if(ReviewQueue)
{
if(SysBase -> ThisTask != (struct Task *)ReviewProcess)
{
BYTE SigBit;
if((SigBit = AllocSignal(-1)) != -1)
{
struct DataMsg Msg;
InitMsgItem(&Msg,ReviewClientDestructor);
Msg . Type = DATAMSGTYPE_UPDATEREVIEW;
Msg . Size = Force;
Msg . Client = SysBase -> ThisTask;
Msg . Mask = 1L << SigBit;
Forbid();
if(ReviewProcess)
{
ClrSignal(Msg . Mask);
PutMsgItem(ReviewQueue,(struct MsgItem *)&Msg);
Wait(Msg . Mask);
}
Permit();
FreeSignal(SigBit);
}
}
else
LocalUpdateReview(Force);
}
}
VOID __regargs
MoveReview(BYTE Mode)
{
if(ReviewQueue)
{
if(SysBase -> ThisTask != (struct Task *)ReviewProcess)
{
BYTE SigBit;
if((SigBit = AllocSignal(-1)) != -1)
{
struct DataMsg Msg;
InitMsgItem(&Msg,ReviewClientDestructor);
Msg . Type = DATAMSGTYPE_MOVEREVIEW;
Msg . Size = Mode;
Msg . Client = SysBase -> ThisTask;
Msg . Mask = 1L << SigBit;
Forbid();
if(ReviewProcess)
{
ClrSignal(Msg . Mask);
PutMsgItem(ReviewQueue,(struct MsgItem *)&Msg);
Wait(Msg . Mask);
}
Permit();
FreeSignal(SigBit);
}
}
else
LocalMoveReview(Mode);
}
}
VOID
DeleteReview()
{
CheckItem(MEN_REVIEW_WINDOW,FALSE);
Forbid();
if(ReviewProcess)
{
ClrSignal(SIG_HANDSHAKE);
Signal(ReviewProcess,SIG_KILL);
Wait(SIG_HANDSHAKE);
}
Permit();
}
BYTE
CreateReview()
{
if(ReviewProcess)
return(TRUE);
else
{
BYTE Result = FALSE;
Forbid();
if(CreateNewProcTags(
NP_Entry, ReviewProcessEntry,
NP_Name, "term Review Process",
NP_Priority, SysBase -> ThisTask -> tc_Node . ln_Pri,
NP_StackSize, 4000,
NP_WindowPtr, -1,
TAG_END))
{
ClrSignal(SIG_HANDSHAKE);
Wait(SIG_HANDSHAKE);
if(ReviewProcess)
{
CheckItem(MEN_REVIEW_WINDOW,TRUE);
Result = TRUE;
}
}
Permit();
return(Result);
}
}